package com.witmore.skyline.web.service.third.yingshi;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;

import java.util.concurrent.ConcurrentHashMap;

@Slf4j
public class YsTokenCache {

    private static final ConcurrentHashMap<String, YSTokenInfo> ysTokenCache = new ConcurrentHashMap<>();

    /**
     * token 过期时间 默认6天 3600 * 24 * 6
     */
    private static final long EXPIRE_TIME = 3600000 * 24 * 6;


    /**
     * 获取token的方法，首先从缓存中查找
     */
    public static String getToken() {
        YSTokenInfo tokenInfo = ysTokenCache.get("ystoken");
        // 如果token存在且有效
        if (!isTokenExpired()) {
            log.info("YS Token from cache: {}", tokenInfo.getAccessToken());
            return tokenInfo.getAccessToken();
        }
        return refreshToken();
    }

    /**
     * 刷新token
     */
    public static String refreshToken() {
        removeToken();
        YSTokenInfo tokenInfo;
        String newToken;
        try {
            newToken = YSApiClient.getAccessToken();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        tokenInfo = new YSTokenInfo(newToken, System.currentTimeMillis() + EXPIRE_TIME);
        ysTokenCache.put("ystoken", tokenInfo);
        return newToken;
    }

    /**
     * 删除token缓存信息
     */
    private static void removeToken() {
        ysTokenCache.remove("ystoken");
    }

    /**
     * 检查 Token 是否过期
     */
    private static boolean isTokenExpired() {
        if (CollectionUtils.isEmpty(ysTokenCache)) {
            return true;
        }
        YSTokenInfo tokenInfo = ysTokenCache.get("ystoken");
        return tokenInfo == null || tokenInfo.getAccessToken() == null
                || tokenInfo.isExpired();
    }

    /**
     * Token信息类，包含token和过期时间 单位：毫秒
     */
    @Data
    static class YSTokenInfo {
        private String accessToken;
        private long expireTime;

        public YSTokenInfo(String accessToken, long expireTime) {
            this.accessToken = accessToken;
            this.expireTime = expireTime;
        }

        public boolean isExpired() {
            return System.currentTimeMillis() > expireTime;
        }
    }
}
